// 命令式编程：原生js开发或者jquery通过命令操作DOM对象完成数据更改，界面变化。
// 声明式编程：框架底层已经封装号模块帮助我们来完成DOM的操作，只需去声明即可使用 vue react angular {{}}
// 编程范式：命令式编程和声明式编程
// 编程范式：面向对象的编程与面向过程的编程
// 面向过程方式 他的第一个公民是函数，他围绕着函数进行编程，也就是函数式编程

const nums = [10,20,111,222,444,40,50]
//1、从nums数组中取出小于100的数
let newNums = []
for (const n of nums) {
    if(n < 100){
        newNums.push(n)
    }
}
console.log(newNums);

//2、从（1）要求中小于100的数都乘以2
let newNewNums = []
for (const n of newNums) {
    newNewNums.push(n*2)
}
console.log(newNewNums);


//3、从（2）要求中，把所有的数进行累加，得到最终结果
let total = 0
for (const n of newNewNums) {
    total += n
}

console.log(total);
//通过js逻辑操作完成需求

//函数式编程
//封装了一些函数用来实现一些效果
//1）filter函数的使用
//参数是一个回调函数，数组有多少个成员，就回调多少次
let newNums1 = nums.filter(function(n){
    //此回调函数编写过滤规则
    //匿名函数，有一个参数n，每次回调数组成员，第一个n是10，第二个是20 以此类推
    //匿名函数被要求必须返回一个值，return，是布尔值，true 返回n进入到新的数组，如果是false就什么都不操作
    return n < 100
})
console.log(newNums1);

// 2）map函数的使用
// 它可以对数组中每个内容进行一些操作
// 参数也为一个匿名的回调函数

let newNewNums1 = newNums1.map(function(n){
    // 参数指代每次回调的数组成员
    return n * 2
})
console.log(newNewNums1);

// 3) reduce函数，第一个参数为回调函数，第二个参数为开始的默认值
// 作用就是对数组所有内容进行一个汇总

let total1 = newNewNums1.reduce(function(preValue,n){
    // 匿名函数中也有两个参数，第一个参数为preValue，指上一个返回的指
    // 第二个参数为n，本次回调数组成员
    return preValue + n
},0)
console.log(total1);

//函数式编程

//把三个需求进行综合，一起提出
let totalnums = nums.filter(function(n){
    return n < 100
}).map(function(n){
    return n * 2
}).reduce(function(preValue,n){
    return preValue + n
},0)

console.log(totalnums);

// 箭头函数参数为一个，括号可省略
// 当箭头函数 函数体 代码只有一行，且是return语句，可省略大括号和return

let totalnums2 = nums.filter(n => n < 100).map(n=> n * 2 ).reduce((preValue,n)=> preValue + n,0)
console.log(totalnums);

